package cn.gzmli.dtt.common.service;

import cn.gzmli.dtt.common.dao.DepartmentDao;
import cn.gzmli.dtt.common.entity.Department;
import cn.gzmli.dtt.common.entity.PageInfo;
import cn.gzmli.dtt.common.utils.*;
import com.xiaoleilu.hutool.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.SystemException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Descript
 * @Author xsx
 * @Date 2017/12/25
 */
@Service
@Transactional
public class DepartmentService extends BaseService<Department> {
    @Autowired
    private UserService userService;

    @Autowired
    private DepartmentDao departmentDao;

    @Override
    public void delete(Department department) throws Exception {
        int childCount = this.childCount(department.getId());
        if (childCount>0){
            throw new SystemException("该部门还有下级部门，如需删除，请先删除该部门的下级部门");
        }
        List<Map<String, Object>> list = userService.findserByDepartmentId(department.getId());

        if (list.size()>0){
            throw new SystemException("该部门还有用户关联，如需删除，请先调整该部门下的用户");
        }
        super.delete(department);
    }

    @Override
    public Department save(Department department) throws Exception {
        Map<String, String> condition = new HashMap<>();
        condition.put("no", "="+ StrUtil.wrap(department.getNo(), "'", "'"));
        Department dept = this.getByCondition(condition);
        if (dept==null){
            condition.put("name", "="+ StrUtil.wrap(department.getName(), "'", "'"));
            dept = this.getByCondition(condition);
            if (dept==null){
                String deptNo = getDeptNo();
                int deptId = (Integer) this.getDao().insert(department);
                department.setId(deptId);
                String updateSql = "UPDATE department SET no=?, orderNo=? WHERE id=?";
                departmentDao.getJdbcTemplate().update(updateSql, deptNo, deptId, deptId);
            }else{
                throw new SystemException("此部门名称已存在");
            }
        }else{
            throw new SystemException("此部门编号已存在");
        }
        return department;
    }

    @Override
    public void update(Department department) throws Exception {
        Map<String, String> condition = new HashMap<>();
        condition.put("no", "="+ StrUtil.wrap(department.getNo(), "'", "'"));
        Department dept = this.getByCondition(condition);
        if (dept==null || dept.getId().intValue()==department.getId().intValue()){
            condition.put("name", "="+ StrUtil.wrap(department.getName(), "'", "'"));
            dept = this.getByCondition(condition);
            if (dept==null || dept.getId().intValue()==department.getId().intValue()){
                departmentDao.update(department);
            }else{
                throw new SystemException("该名称已存在");
            }
        }else{
            throw new SystemException("该编号已存在");
        }
    }

    @Transactional(rollbackFor=Exception.class)
    public void updateSite(Integer orgId, String siteIDs) throws Exception {

        //先移除机构区域信息表,再添加
        String deleteSql = "DELETE FROM org_site WHERE orgId= "+orgId;
        departmentDao.getJdbcTemplate().execute(deleteSql);

        StringBuilder insertSql = new StringBuilder("INSERT INTO org_site (orgId, siteId) ");
        List<Object> args = new ArrayList<Object>();
        if (StrUtil.isNotBlank(siteIDs)){
            for (String siteId : siteIDs.split(",")){
                args.add(orgId);
                args.add(siteId);
                insertSql.append(" SELECT ?,? FROM DUAL UNION");
            }
            String executeSql = insertSql.substring(0, insertSql.lastIndexOf("UNION"));
            departmentDao.getJdbcTemplate().update(executeSql.toString(), args.toArray());
        }
    }

    public List<Map<String,Object>> getOrgSiteTree(Integer orgId)throws Exception{
        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
        StringBuilder sql = new StringBuilder();
        sql.append(" SELECT r.* FROM org_site r WHERE 1=1 AND r.orgId = ? ");
        if (BaseUtil.isNotEmpty(orgId)) {
            data = departmentDao.getJdbcTemplate().queryForList(sql.toString(), orgId);
        }
        return data;
    }

    public List<Map<String, Object>> getTree(HttpServletRequest request) throws Exception {
        Map<String, Object> condition = this.getCondition(request);
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT CONCAT(id, 'dttD') AS id,")
            .append("id AS realID,")
            .append("name AS name,")
            .append("orderNo,")
            .append("CONCAT(pId, 'dttD') AS pId,")
            .append("'Department' AS nodeType ")
            .append("FROM department d ")
            .append("WHERE 1=1 ");
        return BaseUtil.getData(sql, condition, this.getDao());
    }

    public List<Map<String, Object>> listOrgTree(HttpServletRequest request) throws Exception {
        Map<String, Object> condition = this.getCondition(request);
        StringBuilder sql = new StringBuilder();
        Integer bigType=null;
        sql.append("select DISTINCT CONCAT(d.id, 'dttD') AS id,d.id AS realID,d.name AS name, ")
                .append("d.orderNo,CONCAT(d.pId, 'dttD') AS pId,'Department' AS nodeType ")
                .append("FROM department d ")
                .append("LEFT JOIN proccompact p ON p.sellerOrgId =  d.id ")
                .append("LEFT JOIN proccompact_section ps ON ps.procCompactId = p.procCompactId ");
                if(request.getParameter("providerOrgType")!=null){
                    sql.append(" LEFT JOIN proccompactmat pcm ON p.procCompactId=pcm.procCompactId ");
                    sql.append(" LEFT JOIN mattype mt ON mt.matTypeId=pcm.matTypeId ");
                    bigType=Integer.parseInt(request.getParameter("providerOrgType"));
                }
                sql.append("WHERE 1=1 ");
                if( bigType!=null){
                    sql.append(" AND mt.bigType="+bigType+" ");
                }
        return BaseUtil.getData(sql, condition, this.getDao());
    }

    private int childCount(Integer id) throws Exception {
        final String sql = "SELECT COUNT(*) FROM department WHERE pid=?";
        return this.getDao().getJdbcTemplate().queryForObject(sql, Integer.class, id);
    }

    /**
     * 根据用户id获取用户所属机构信息
     * @author wonderful
     * @param userId
     * @return
     * @throws Exception
     * 20180711
     */
    public List<Map<String, Object>> quseryUserOrgs(Integer userId) throws Exception {

        StringBuffer sql=new StringBuffer("SELECT uo.userId AS userId,");
        sql.append("uo.orgId AS orgId,");
        sql.append("o.name AS orgName ");
        sql.append(" FROM user_org uo LEFT JOIN department o ON uo.orgId=o.id ");
        sql.append(" WHERE uo.userId IN ");

        List<Object> args=BaseUtil.toInConds(sql,userId.toString());
        sql.append(" GROUP BY uo.userId ");

        List<Map<String, Object>> orgs=null;

        if(args!=null){
            orgs=this.getDao().getJdbcTemplate().queryForList(sql.toString(),args.toArray());
        }

        return orgs;

    }

    public List<Map<String,Object>> getByCondition(HttpServletRequest request, PageInfo pageInfo)throws Exception{
        Map<String, Object> condition = this.getCondition(request);
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT d.* ,pd.name pName ");
        sql.append(" from department d ");
        sql.append(" LEFT JOIN department pd ON pd.id=d.pId ");
        //sql.append(" LEFT JOIN region r ON r.id=d.regionId ");
        sql.append(" WHERE 1=1 ");
        List<Map<String, Object>> data = new ArrayList<>();
        if (pageInfo.getPageSize()>0){
            data.addAll(BaseUtil.getData(sql, condition, pageInfo, this.getDao(), "d.orderNo", true));
        }else {
            data.addAll(BaseUtil.getData(sql, condition, this.getDao()));
        }
        return data;
    }

    public Map<String, Object> getCondition(HttpServletRequest request) throws Exception{
        Map<String, Object> condition = new HashMap<>();

        if (StrUtil.isNotBlank(request.getParameter("depId"))){
            condition.put(" AND d.id =?",Integer.valueOf(request.getParameter("depId")));
        }

        if (StrUtil.isNotBlank(request.getParameter("name"))){
            condition.put(" AND d.name LIKE ?", "%"+request.getParameter("name").trim()+"%");
        }
        if (StrUtil.isNotBlank(request.getParameter("no"))){
            condition.put(" AND d.no LIKE ?", "%"+request.getParameter("no").trim()+"%");
        }
        if (StrUtil.isNotBlank(request.getParameter("type"))){
            condition.put(" AND d.type =?",Integer.valueOf(request.getParameter("type")));
        }
        if (StrUtil.isNotBlank(request.getParameter("parentIDS"))){
            condition.put(" AND d.pid IN("+ BaseUtil.getPlaceholder(BaseUtil.getPlaceholderSize(request.getParameter("parentIDS")))+")", BaseUtil.getArgs(request.getParameter("parentIDS"), Integer.class));
        }

        if (StrUtil.isNotBlank(request.getParameter("projectId"))){
            condition.put(" AND p.projectId =?",Integer.valueOf(request.getParameter("projectId")));
        }
        if (StrUtil.isNotBlank(request.getParameter("sectionId"))){
            condition.put(" AND ps.sectionId IN("+ BaseUtil.getPlaceholder(BaseUtil.getPlaceholderSize(request.getParameter("sectionId")))+")", BaseUtil.getArgs(request.getParameter("sectionId"), Integer.class));
        }
        if (StrUtil.isNotBlank(request.getParameter("procCompactStatus"))){
            condition.put(" AND p.procCompactStatus =?",Integer.valueOf(request.getParameter("procCompactStatus")));
        }
        return condition;
    }

    /**
     * 根据机构ID查询所有父级机构信息
     * @date 2019-09-20
     * @param departmentId
     * @return
     * @throws Exception
     */
    public List<Department> getAllParentDepartmentById(Integer departmentId) throws Exception {
        List<Department> departments = new ArrayList<Department>();
        if (!BaseUtil.isNotEmpty(departmentId)) {
            return departments;
        }
        StringBuilder sql = new StringBuilder("SELECT T2.* FROM ( ");
        sql.append("SELECT @r AS _id, (SELECT @r := pid FROM department WHERE id = _id) AS pid, @l := @l + 1 AS lvl ")
                .append("FROM (SELECT @r := "+departmentId+", @l := 0) vars, department h  WHERE @r <> 0) T1 ")
                .append("JOIN department T2 ON T1._id = T2.id ")
                .append("ORDER BY T2.orderNo DESC ");

        departments = this.getDao().getJdbcTemplate().query(sql.toString(), new LocalRowMapper(Department.class));

        return departments;
    }

    public static String getDeptNo() {
        String[] letters={"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
        StringBuilder result = new StringBuilder();
        result.append(DateUtils.getNowDateShortTime());
        result.append(letters[(int)Math.floor(Math.random()*26) ]);
        result.append(letters[(int)Math.floor(Math.random()*26) ]);
        result.append(letters[(int)Math.floor(Math.random()*26) ]);
        result.append(letters[(int)Math.floor(Math.random()*26) ]);
        return result.toString();
    }
}
